#ifndef COMPETENCECLASSE_H
#define COMPETENCECLASSE_H 1

#include "ADDArticleObjet.h"

#include <string>

/**
 * Permet de gérer le type de compétence.
 */
enum ScoreAdditionnel {
  Normal,      /**< Compétence "normale", pouvant être associée à un
		  pourcentage */
  Basique,    /**< Compétence associée à un nombre dépendant du
		 niveau */
  Pourcentage /**< Compétence associée à un pourcentage dépendant du
		 niveau */
};

/**
 * Gestion des compétences de classe. Permet d'associer le nom de la
 * compétence à un coût, un éventuel pourcentage de base et permet de
 * préciser si la compétence est associée à un autre score, dépendant
 * du niveau. En faire une classe permet de jouir des mêmes avantages
 * que pour CapaciteRaciale
 *
 * Une compétence de classe peut être encore plus compliquée : un
 * alias peut être défini (utile pour les écoles de magie / sphères de
 * pouvoir), elle peut doner accès à une autre liste de compétence,
 * avoir un score associé au niveau (score sur 20 ou sur 100). Toutes
 * ces fonctionnalités sont implémentées ici.
 *
 * @author Johan "Solo" Luisier.
 */
class CompetenceClasse : public ADDArticleObjet
{
 public:
  CompetenceClasse( const std::string& comp = "", const unsigned& prix = 0,
		    const ScoreAdditionnel& autre = Normal );
  CompetenceClasse( const std::string& comp, const std::string& alias,
		    const unsigned& prix );
  CompetenceClasse( const std::string& comp, const unsigned& prix,
		    const bool& pourcentage, const unsigned& valBase );
  CompetenceClasse( const std::string& comp, const unsigned& prix,
		    const unsigned& base, const unsigned& indice = 0,
		    const bool& exclu = false);
  CompetenceClasse( const std::string& comp,
		    const unsigned& prix, const std::string& typeObjet );
  CompetenceClasse( const CompetenceClasse& lsComp );
  virtual ~CompetenceClasse();
  CompetenceClasse& operator=( const CompetenceClasse& lsComp );
  const std::string& aliasNom() const;
  void setAliasNom( const std::string& alias );
  const bool& aliasDefini() const;
  const bool& pourcentage() const;
  const unsigned& valeurBase() const;
  const ScoreAdditionnel& autreScore() const;
  const unsigned& sousCategorie() const;
  const unsigned& adresseBase() const;
  const bool& sousCategorieDefinie() const;
  const bool& choixExclusif() const;
  
  /**
   * Permet de réaliser l'affichage simple d'une CompetenceClasse. Le
   * nom et le coût sont affichés, et les éventuels autres attributs,
   * tels que le pourcentage de base, ou alors si elle est associée à
   * un score dépendant du niveau.
   *
   * @param os flot de sortie sur lequel on veut écrire.
   * @param lsComp capacité que l'on veut écrire.
   *
   * @return le flot os, modifié.
   */
  friend ostream& operator<<( ostream& os, const CompetenceClasse& lsComp );
  /**
   * Permet de réaliser l'affichage simple d'une CompetenceClasse. Le
   * nom et le coût sont affichés, et les éventuels autres attributs,
   * tels que le pourcentage de base, ou alors si elle est associée à
   * un score dépendant du niveau.
   *
   * @param flot instance de FlotMessage dans laquelle on veut écrire.
   * @param lsComp capacité que l'on veut écrire.
   *
   * @return flot, une fois modifié.
   */
  friend FlotMessage& operator<<( FlotMessage& flot,
				  const CompetenceClasse& lsComp );
 protected:
  std::string AliasNom; /**< Nom de la compétence, utilisé pour la
		       génération des noms de fichiers / dossiers. */
  bool AliasDefini;
  bool Pourcentage;  /**< Associé à un pourcentage ? */
  unsigned ValeurBase; /**< Valeur de base d'une compétence
			      associée à un pourcentage (du type
			      talent de Voleur). */
  ScoreAdditionnel AutreScore; /**< Associé à un score dépendant du
				  niveau ? */
  unsigned SousCategorie; /**< Tentative de résoudre le pb des talents
			     de voleurs pour mages. */
  unsigned AdresseBase; /**< Offset appliqué à la compétence lors
			       du stockage dans
			       Classe::Comp_classe. */
 private:
  /**
   * Permet de savoir si la compétence a un pointeur vers une autre
   * liste de compétences, càd si c'est une compétence à tiroir.
   */
  bool SousCategorieDefinie;
  /**
   * Permet de savoir si le choix parmi les compétences "à tiroir" est
   * exclusif ou non.
   */
  bool ChoixExclusif;
};

const CompetenceClasse& competenceClasseInconnue();

#endif // COMPETENCECLASSE_H
